package DFGA.population;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import org.omg.CORBA.PUBLIC_MEMBER;

import abstractGA.chrom.Chrom;
import abstractGA.popu.Population;
import nsga.population.PopuHelper;

public class DFGAPopu extends Population {
	// 存放成功的变异因子
	protected static ArrayList<Float> mutFactors = new ArrayList<Float>();
	// 存放成功的交叉概率
	protected static ArrayList<Float> crobs = new ArrayList<Float>();
	// 外部文档，用于存放被淘汰染色体
	protected static List<Chrom> archieves = new ArrayList<Chrom>();
	
	protected static Robot robot= null;

	public DFGAPopu() {
		super();
	}
	
//	public static  List<StringBuffer> convertOriginalCodetoMLCode(List<StringBuffer> mlDFcodes,List<Integer> idxs){
//		List<StringBuffer> codes = new ArrayList<>();
//		
//		for(int i=0;i<mlDFcodes.size();i++){
//			if(i<idxs.get(0)){
//				codes.add(mlDFcodes.get(i));
//			}else if(i<idxs.get(1)){
//				if(mlDFcodes.get(i).toString().equals("ApplicationServer"))
//				codes.add(new StringBuffer("1"));
//				if (mlDFcodes.get(i).toString().equals("DBServerMain")) {
//					codes.add(new StringBuffer("2"));
//				}
//				if (mlDFcodes.get(i).toString().equals("DBServerBackup")) {
//					codes.add(new StringBuffer("3"));
//				}
//			}else {
//				if (mlDFcodes.get(i).toString().equals("UserInteraction")) {
//					codes.add(new StringBuffer("1"));
//				}
//				if (mlDFcodes.get(i).toString().equals("UserInteractionComfort")) {
//					codes.add(new StringBuffer("2"));
//				}
//				if (mlDFcodes.get(i).toString().equals("FileLoader")) {
//					codes.add(new StringBuffer("1"));
//				}
//				if (mlDFcodes.get(i).toString().equals("FileLoaderPower")) {
//					codes.add(new StringBuffer("2"));
//				}
//				if (mlDFcodes.get(i).toString().equals("Encoder")) {
//					codes.add(new StringBuffer("1"));
//				}
//				if (mlDFcodes.get(i).toString().equals("EncoderPower")) {
//					codes.add(new StringBuffer("2"));
//				}
//			}
//		}
//		
//		return codes;
//	}

	/**
	 * 获取种群中最优染色体集合
	 */
	@Override
	public List<Chrom> getBestChroms() {
		List<Chrom> bestChroms = new ArrayList<Chrom>();
		float minCost = Float.MAX_VALUE;
		int idx = -1;
		int size = chroms.size();
		if (size > 0) {
			for (int i = 0; i < size; i++) {
				Chrom chrom = chroms.get(i);
				if (Boolean.parseBoolean(chrom.getObjVals().get(0).toString().trim())==false) {
					break;
				}
				if (robot==null) {
					try {
						robot = new Robot();
					} catch (AWTException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
//				robot.keyPress(KeyEvent.VK_ALT);
//				robot.keyPress(KeyEvent.VK_F4);
//				robot.keyRelease(KeyEvent.VK_F4);
//				robot.keyRelease(KeyEvent.VK_ALT);
				float curCost = Float.parseFloat(chrom.getObjVals().get(1).toString().trim());
				if (Float.compare(minCost, curCost) > 0) {
					minCost = curCost;
					idx = i;
				}
			}
//			bestChroms.add(chroms.get(idx).copy());
		}
		return bestChroms;
	}

	/**
	 * 对种群进行差分演化操作（包括了变异和交叉）
	 * 
	 * @param curMutFactor:当前的变异因子
	 * @param curCrob：当前的交叉概率
	 * @throws Exception 
	 */
	
	enum Dominate{
		DOMIN ,DOMINED,NONDOMIN
	}
	
	public void geneticOpt() throws Exception {
		int popSize = chroms.size();
		for (int i = 0; i < popSize; i++) {
			// 变异
			Chrom optChrom = chroms.get(i).copy();// 对种群中第i染色体进行复制
			//生成一个变异Vector，然后对当前个体进行单点变异
			List<StringBuffer> srcCodes = optChrom.getCodes();
			int dimension = srcCodes.size();
			int  mutateStrategy = random.nextInt(3);
			int crossoverStrategy = random.nextInt(2);
			List<Float> mutVector = getMutVector(dimension);
			List<StringBuffer> destCodes = muteAChrom(mutateStrategy,srcCodes, mutVector,optChrom);
			
			// 交叉
			List<Float> crValue = getCrob(dimension);
			List<StringBuffer> newCodes = crossover(srcCodes, destCodes, crValue,crossoverStrategy,dimension);
			optChrom.setCodes(newCodes);
			
			if (Boolean.parseBoolean(optChrom.getObjVals().get(0).toString().trim())) {
				if (Float.parseFloat(optChrom.getObjVals().get(1).toString().trim())<Float.parseFloat(chroms.get(i).getObjVals().get(1).toString().trim())) {
					chroms.set(i, optChrom);
				}
			}
//			float optRest =  optChrom.getObjVals().get(0).toString().trim();
//			float optCost = optChrom.getObjVals().get(1);
//			
//			float curRest = chroms.get(i).getObjVals().get(0);
//			float curCost = chroms.get(i).getObjVals().get(2);
//			
//			
//			switch (judgeDomin(optRest,optCost,curRest,curCost)) {
//			case DOMIN:
//				chroms.set(i, optChrom);
//				break;
//			case DOMINED:
//				break;
//			case NONDOMIN:
//				nonChroms.add(optChrom);
//			default:
//				break;
//			}
//			nonChroms.add(chroms.get(i));
		}
		
//		PopuHelper popuHelper =new PopuHelper();
//		Population nextPopulation=envSelect1(nonChroms, popuHelper,popSize);
//		
//		return nextPopulation;
		//进行非支配排序，然后然后生成下一代个体
	}
	public Population envSelect1(List<Chrom> nextChroms,PopuHelper popuHelper,int popuSize) {
		Population nxtPopu = copy();
		nxtPopu.add(nextChroms);
		ArrayList<ArrayList<Integer>> idxss = popuHelper.nondominatedSort(nxtPopu
				.getChroms());
		ArrayList<Chrom> selChroms = new ArrayList<Chrom>();
		int i = 0;
		ArrayList<Integer> frontIdxs = idxss.get(i);
		int frontSize = frontIdxs.size();
		int selSize = 0;
		while (selSize + frontSize <= popuSize) {
			for (Integer frontIdx : frontIdxs) {
				selChroms.add(nxtPopu.getChroms().get(frontIdx).copy());
			}
			selSize = selChroms.size();
			i += 1;
			if (i < idxss.size()) {
				frontIdxs = idxss.get(i);
				frontSize = frontIdxs.size();
			} else {
				break;
			}
		}
		selSize = selChroms.size();
		if (selSize < popuSize && selSize + frontSize > popuSize) {
			List<Float> dists = popuHelper.getCrowdDistances(nxtPopu.getChroms(),
					frontIdxs);
			ArrayList<Integer> sortedIdxs = popuHelper.publeSort(dists, frontIdxs);
			int len = popuSize - selSize;
			for (int k = 0; k < len; k++) {
				int selIdx = sortedIdxs.get(k);
				selChroms.add(nxtPopu.getChroms().get(selIdx));
			}

		}
		nxtPopu.getChroms().clear();
		nxtPopu.setChroms(selChroms);
		return nxtPopu;
	}

	//判断两个个体中的两个目标值的支配情况
	private Dominate judgeDomin(float optRest,float optCost,float curRest,float curCost) {
		if ((optRest<curRest&&optCost<=curCost)||(optRest<=curRest&&optCost<curCost)) {
			return Dominate.DOMIN;
		}else if ((curRest<optRest&&curCost<=optCost)||(curRest<=optRest&&curCost<optCost)) {
			return Dominate.DOMINED;
		}else 
		return Dominate.NONDOMIN;
	}

	/**
	 * 对一个染色体进行变异
	 * 
	 * @param srcCodes:变异前染色体的编码
	 * @param factor：变异因子
	 * @param topNum：前多少个最优染色体
	 * @param unionChroms：当前种群与外部文档中染色体的并集
	 * @return：变异后染色体的编码
	 */
	public List<StringBuffer> muteAChrom(int mutateStrategy,List<StringBuffer> srcCodes, List<Float> factor,Chrom curChrom) {
		List<StringBuffer> newCodes = new ArrayList<StringBuffer>();
		int popSize = chroms.size();	
		switch (mutateStrategy) {
			case 0:
				for(int i=0;i<srcCodes.size();i++){
				int r1 = random.nextInt(popSize);
				int r2 = random.nextInt(popSize);
				int r3 = random.nextInt(popSize);
				while (r1==r2||r2==r3||r1==r3) {
					 r1 = random.nextInt(popSize);
					 r2 = random.nextInt(popSize);
					 r3 = random.nextInt(popSize);
					}
				StringBuffer str1  = chroms.get(r1).getCodes().get(i);
				StringBuffer str2  = chroms.get(r2).getCodes().get(i);
				StringBuffer str3  = chroms.get(r3).getCodes().get(i);
				if(i<1){
					float speedfactor = factor.get(i);
					StringBuffer speedstr = mutSpeed1(speedfactor,str1,str2,str3);
					newCodes.add(speedstr);
				}else  {
					float deplyCodeFactor = factor.get(i);
					StringBuffer deplystr = mutDeply1(deplyCodeFactor,str1,str2,str3);
					newCodes.add(deplystr);
				}
				}
				break;
			case 1:
				for(int i=0;i<srcCodes.size();i++){
					int r1 = random.nextInt(popSize);
					int r2 = random.nextInt(popSize);
					while (r1==r2) {
						 r1 = random.nextInt(popSize);
						 r2 = random.nextInt(popSize);
						}
				StringBuffer str1  = curChrom.getCodes().get(i);
				StringBuffer str2  = chroms.get(r1).getCodes().get(i);
				StringBuffer str3  = chroms.get(r2).getCodes().get(i);
				if(i<1){
					float speedfactor = factor.get(i);
					StringBuffer speedstr = mutSpeed1(speedfactor,str1,str2,str3);
					newCodes.add(speedstr);
				}else {
					float deplyCodeFactor = factor.get(i);
					StringBuffer deplystr = mutDeply1(deplyCodeFactor,str1,str2,str3);
					newCodes.add(deplystr);
				}
				}
				break;
			case 2:
				for(int i=0;i<srcCodes.size();i++){
					int r1 = random.nextInt(popSize);
					int r2 = random.nextInt(popSize);
					int r3 = random.nextInt(popSize);
					while (r1==r2||r2==r3||r1==r3) {
						 r1 = random.nextInt(popSize);
						 r2 = random.nextInt(popSize);
						 r3 = random.nextInt(popSize);
						}
					StringBuffer str1  = chroms.get(r1).getCodes().get(i);
					StringBuffer str2  = chroms.get(r2).getCodes().get(i);
					StringBuffer str3  = chroms.get(r3).getCodes().get(i);
					if(i<1){
						float speedfactor = factor.get(i);
						StringBuffer speedstr = mutSpeed1(speedfactor,str1,str2,str3);
						newCodes.add(speedstr);
					}else {
						float deplyCodeFactor = factor.get(i);
						StringBuffer deplystr = mutDeply1(deplyCodeFactor,str1,str2,str3);
						newCodes.add(deplystr);
					}
				}
					break;
			default:
				break;
			}
		return newCodes;
	}

	/**
	 * 两个选定的染色体进行交叉
	 * 
	 * @param srcCodes：源染色体编码
	 * @param destCodes：目标染色体编码
	 * @return：交叉后染色体的编码
	 */
	public List<StringBuffer> crossover(List<StringBuffer> srcCodes,List<StringBuffer> destCodes,List<Float> crValue,int crossoverStrategy,int dimension) {
		List<StringBuffer> newCodes = new ArrayList<>();
		switch (crossoverStrategy) {
		case 0:
			int randPos = random.nextInt(dimension);
			for(int i=0;i<dimension;i++){
				float randValue = random.nextFloat();
				if(i==randPos||randValue<crValue.get(i)){
					newCodes.add(destCodes.get(i));
				}else {
					newCodes.add(srcCodes.get(i));
				}
			}
			break;
		case 1:
			int randpos1 = random.nextInt(dimension);
			int randpos2 = random.nextInt(dimension);
			int low = -1;
			int high = -1;
			
			if(randpos1+randpos2<=dimension){
				low = randpos1;
				high = randpos1+randpos2;
			}else {
				low = (randpos1+randpos2)%dimension;
				high = dimension;
			}
			
			for(int i=0;i<dimension;i++){
				if(i>=low&&i<=high){
					newCodes.add(destCodes.get(i));
				}else {
					newCodes.add(srcCodes.get(i));
				}
			}
			break;
		default:
			break;
		}
		return newCodes;
		
	}

	/**
	 * 按均匀分布产生[0.1,curFactor)的变异因子
	 * 
	 * @param curFactor：当前变异因子
	 * @return
	 */
	public List<Float> getMutVector(int dimension) {
		List<Float> value = new ArrayList<>();
		for(int i=0;i<dimension;i++){
			float factor = random.nextFloat()*5/10+0.5f;
			value.add(factor);
		}
		return value;
	}

	/**
	 * 按柯西分布产生[0.1,curCrob)的交叉概率
	 * 
	 * @param curCrob:当前交叉概率
	 * @return
	 */
	public List<Float> getCrob(int dimension) {
		List<Float> value = new ArrayList<>();
		for(int i=0;i<dimension;i++){
			value.add(random.nextFloat());
		}

		return value;
	}

	/**
	 * 对源染色体中0-3位编码表示的速度值进行变异
	 * 
	 * @param factor:变异因子
	 * @param srcCodes：源染色体编码
	 * @param bestPCodes：P最优染色体编码
	 * @param r1Codes：r1染色体编码
	 * @param r2Codes：r2染色体编码
	 * @return：变异后各处理器速度值的编码
	 */
	public StringBuffer mutSpeed1(float factor,StringBuffer str1,StringBuffer str2,StringBuffer str3) {
		StringBuffer newSpeedCode = new StringBuffer();

		int  r1Speed = Integer.valueOf(str1.toString().trim());

		int r2Speed = Integer.valueOf(str2.toString().trim());
		
		int r3Speed = Integer.valueOf(str3.toString().trim());

		int newSpeed = (int)Math.floor(r1Speed + factor * (r2Speed - r3Speed));
		
		// 较最小值小
		if (Integer.compare(1, newSpeed) > 0) {
			newSpeed = (r1Speed + 1)/2;
		}
		// 较最大值大
		if (Float.compare(newSpeed, 82) > 0) {
			newSpeed = (r1Speed + 82)/2;
		}
		newSpeedCode.append(newSpeed);
		return newSpeedCode;
	}
	
//	public List<StringBuffer> mutSpeed(float factor, List<StringBuffer> srcCodes, List<StringBuffer> bestPCodes,
//			List<StringBuffer> r1Codes, List<StringBuffer> r2Codes) {
//		List<StringBuffer> newSpeedCodes = new ArrayList<StringBuffer>();
//		if (isEqualLen(srcCodes, bestPCodes, r1Codes, r2Codes)) {
//			List<Float> curSpeeds = new ArrayList<Float>();
//			List<Float> bestSpeeds = new ArrayList<Float>();
//			List<Float> r1Speeds = new ArrayList<Float>();
//			List<Float> r2Speeds = new ArrayList<Float>();
//			for (int j = 0; j < 6; j++) {
//				String tempStr = srcCodes.get(j).toString();
//				float srcSpeed = Float.valueOf(tempStr);
//				curSpeeds.add(srcSpeed);
//
//				tempStr = bestPCodes.get(j).toString();
//				float bestPSpeed = Float.valueOf(tempStr);
//				bestSpeeds.add(bestPSpeed);
//
//				tempStr = r1Codes.get(j).toString();
//				float r1Speed = Float.valueOf(tempStr);
//				r1Speeds.add(r1Speed);
//
//				tempStr = r2Codes.get(j).toString();
//				float r2Speed = Float.valueOf(tempStr);
//				r2Speeds.add(r2Speed);
//
//				float newSpeed = srcSpeed + factor * (bestPSpeed - srcSpeed) + factor * (r1Speed - r2Speed);
//				// 较最小值小
//				if (Float.compare(0.5f, newSpeed) > 0) {
//					newSpeed = (0.5f + srcSpeed) / 2f;
//				}
//				// 较最大值大
//				if (Float.compare(newSpeed, 2f) > 0) {
//					newSpeed = (2f + srcSpeed) / 2f;
//				}
//				newSpeedCodes.add(new StringBuffer(String.valueOf(newSpeed)));
//			}
//		}
//		return newSpeedCodes;
//	}
//	public List<StringBuffer> mutSpeed(float factor, List<StringBuffer> srcCodes, List<StringBuffer> bestPCodes,
//			List<StringBuffer> r1Codes, List<StringBuffer> r2Codes) {
//		List<StringBuffer> newSpeedCodes = new ArrayList<StringBuffer>();
//		if (isEqualLen(srcCodes, bestPCodes, r1Codes, r2Codes)) {
//			List<Float> curSpeeds = new ArrayList<Float>();
//			List<Float> bestSpeeds = new ArrayList<Float>();
//			List<Float> r1Speeds = new ArrayList<Float>();
//			List<Float> r2Speeds = new ArrayList<Float>();
//			for (int j = 0; j < 3; j++) {
//				String tempStr = srcCodes.get(j).toString();
//				float srcSpeed = Float.valueOf(tempStr);
//				curSpeeds.add(srcSpeed);
//
//				tempStr = bestPCodes.get(j).toString();
//				float bestPSpeed = Float.valueOf(tempStr);
//				bestSpeeds.add(bestPSpeed);
//
//				tempStr = r1Codes.get(j).toString();
//				float r1Speed = Float.valueOf(tempStr);
//				r1Speeds.add(r1Speed);
//
//				tempStr = r2Codes.get(j).toString();
//				float r2Speed = Float.valueOf(tempStr);
//				r2Speeds.add(r2Speed);
//
//				float newSpeed = srcSpeed + factor * (bestPSpeed - srcSpeed) + factor * (r1Speed - r2Speed);
//				// 较最小值小
//				if (Float.compare(2f, newSpeed) > 0) {
//					newSpeed = (2f + srcSpeed) / 2f;
//				}
//				// 较最大值大
//				if (Float.compare(newSpeed, 8f) > 0) {
//					newSpeed = (8f + srcSpeed) / 2f;
//				}
//				newSpeedCodes.add(new StringBuffer(String.valueOf(newSpeed)));
//			}
//		}
//		return newSpeedCodes;
//	}

	/**
	 * 对源染色体中4-12位编码表示的各软件构件部署方案进行变异
	 * 
	 * @param factor:变异因子
	 * @param srcCodes：源染色体编码
	 * @param bestPCodes：P最优染色体编码
	 * @param r1Codes：r1染色体编码
	 * @param r2Codes：r2染色体编码
	 * @return：变异后各软件构件部署方案的编码
	 */
	public StringBuffer mutDeply1(float factor, StringBuffer str1,StringBuffer str2,StringBuffer str3) {
		StringBuffer newDeplyCode = null;
		int len = str1.length();
		int r1SvrNo = Integer.parseInt(str1.toString().trim());

		int r2SvrNo = Integer.parseInt(str2.toString().trim());
		
		int r3SvrNo = Integer.parseInt(str3.toString().trim());

		int newSrvNo = (int) Math
				.floor(r1SvrNo + factor * (r2SvrNo - r3SvrNo));
		// 较最小值小
		if (newSrvNo < 1) {
			newSrvNo = (1 + r1SvrNo) / 2;
		}
		// 较最大值大
		if (newSrvNo > 5000) {
			newSrvNo = (5000 + r1SvrNo) / 2;
		}
		String newSvrName = ""+newSrvNo;
		newDeplyCode = new StringBuffer(newSvrName);
		return newDeplyCode;
	}
	
//	public StringBuffer mutDeply1(float factor, StringBuffer str1,StringBuffer str2,StringBuffer str3) {
//		StringBuffer newDeplyCode = null;
//		int r1SvrNo=0;
//		int r2SvrNo=0;
//		int r3SvrNo=0;
//		switch (str1.toString()) {
//		case "ApplicationServer":
//			r1SvrNo=1;
//			break;
//		case "DBServerMain":
//			r1SvrNo=2;
//			break;
//		case "DBServerBackup":
//			r1SvrNo=3;
//			break;
//			
//		default:
//			break;
//		}
//		switch (str2.toString()) {
//		case "ApplicationServer":
//			r2SvrNo=1;
//			break;
//		case "DBServerMain":
//			r2SvrNo=2;
//			break;
//		case "DBServerBackup":
//			r2SvrNo=3;
//			break;
//		}
//		switch (str3.toString()) {
//		case "ApplicationServer":
//			r3SvrNo=1;
//			break;
//		case "DBServerMain":
//			r3SvrNo=2;
//			break;
//		case "DBServerBackup":
//			r3SvrNo=3;
//			break;
//			
//		default:
//			break;
//		}
//		
//
//		int newSrvNo = (int) Math
//				.floor(r1SvrNo + factor * (r2SvrNo - r3SvrNo));
//		// 较最小值小
//		if (newSrvNo < 1) {
//			newSrvNo = (1 + r1SvrNo) / 2;
//		}
//		// 较最大值大
//		if (newSrvNo > 3) {
//			newSrvNo = (3 + r1SvrNo) / 2;
//		}
//		String newSvrName="";
//		switch (newSrvNo) {
//		case 1:
//			newSvrName="ApplicationServer";
//			break;
//		case 2:
//			newSvrName="DBServerMain";
//			break;
//		case 3:
//			newSvrName="DBServerBackup";
//			break;
//
//		default:
//			break;
//		}
//		newDeplyCode = new StringBuffer(newSvrName);
//		return newDeplyCode;
//	}
//	
//	public StringBuffer mutCompSel1(float factor ,StringBuffer str1,StringBuffer str2,StringBuffer str3) {
//		StringBuffer newCompSelCode = null;
//			// 可选组件{CoreOnlineEngine，CoreGraphicEngine}
//			List<String> compNms = new ArrayList<String>();
//			
//			if (str1.toString().trim().equals("UserInteraction")||str1.toString().equals("UserInteractionComfort")) {
//				compNms.add("UserInteraction");
//				compNms.add("UserInteractionComfort");
//			}
//			if (str1.toString().trim().equals("FileLoader")||str1.toString().equals("FileLoaderPower")) {
//				compNms.add("FileLoader");
//				compNms.add("FileLoaderPower");
//			}
//			if (str1.toString().trim().equals("Encoder")||str1.toString().equals("EncoderPower")) {
//				compNms.add("Encoder");
//				compNms.add("EncoderPower");
//			}
//			String r1CmpNm = str1.toString().trim();
//			String r2CmpNm = str2.toString().trim();
//			String r3CmpNm = str3.toString().trim();
//			String newCmpName = selComp1(factor, compNms, r1CmpNm, r2CmpNm, r3CmpNm);
//			newCompSelCode=new StringBuffer(newCmpName);
//
////			// 可选组件{WebServer、WebServer2和WebServer3}
////			compNms.clear();
////			compNms.add("WebServer");
////			compNms.add("WebServer2");
////			compNms.add("WebServer3");
////
////			curCmpNm = srcCodes.get(19).toString().trim();
////			bestPCmpNm = bestPCodes.get(19).toString().trim();
////			r1CmpNm = r1Codes.get(19).toString().trim();
////			r2CmpNm = r2Codes.get(19).toString().trim();
////			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
////			newCompSelCodes.add(new StringBuffer(newCmpName));
////
////			// 可选组件{GraphicalReporting和GraphicalReporting2}
////			compNms.clear();
////			compNms.add("GraphicalReporting");
////			compNms.add("GraphicalReporting2");
////
////			curCmpNm = srcCodes.get(20).toString().trim();
////			bestPCmpNm = bestPCodes.get(20).toString().trim();
////			r1CmpNm = r1Codes.get(20).toString().trim();
////			r2CmpNm = r2Codes.get(20).toString().trim();
////			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
////			newCompSelCodes.add(new StringBuffer(newCmpName));
////
////			// 可选组件{UserManagement和UserManagement2}
////			compNms.clear();
////			compNms.add("UserManagement");
////			compNms.add("UserManagement2");
////
////			curCmpNm = srcCodes.get(21).toString().trim();
////			bestPCmpNm = bestPCodes.get(21).toString().trim();
////			r1CmpNm = r1Codes.get(21).toString().trim();
////			r2CmpNm = r2Codes.get(21).toString().trim();
////			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
////			newCompSelCodes.add(new StringBuffer(newCmpName));
//		return newCompSelCode;
//	}
	
//	public StringBuffer mutDeply1(float factor, StringBuffer str1,StringBuffer str2,StringBuffer str3) {
//		StringBuffer newDeplyCode = null;
////		if (str1.toString().equals("Server3-2")) {
////			str1 = new StringBuffer("Server5");
////		}
////		if (str2.toString().equals("Server3-2")) {
////			str2 = new StringBuffer("Server5");
////		}
////		if (str3.toString().equals("Server3-2")) {
////			str3 = new StringBuffer("Server5");
////		}
//		
//		int len = str1.length();
//		String code = str1.toString().trim();
//		int r1SvrNo = Integer.parseInt(code.substring(len - 1));
//
//		code = str2.toString().trim();
//		int r2SvrNo = Integer.parseInt(code.substring(len - 1));
//		
//		code = str3.toString().trim();
//		int r3SvrNo = Integer.parseInt(code.substring(len - 1));
//
//		int newSrvNo = (int) Math
//				.floor(r1SvrNo + factor * (r2SvrNo - r3SvrNo));
//		// 较最小值小
//		if (newSrvNo < 1) {
//			newSrvNo = (1 + r1SvrNo) / 2;
//		}
//		// 较最大值大
//		if (newSrvNo > 4) {
//			newSrvNo = (4 + r1SvrNo) / 2;
//		}
//		String newSvrName = "server" + newSrvNo;
////		if (newSvrName.equals("Server5")) {
////			newSvrName = "Server3-2";
////		}
//		newDeplyCode = new StringBuffer(newSvrName);
//		return newDeplyCode;
//	}

	/**
	 * 对源染色体中18-21位编码表示的四种可选构件进行变异
	 * 
	 * @param factor:变异因子
	 * @param srcCodes：源染色体编码
	 * @param bestPCodes：P最优染色体编码
	 * @param r1Codes：r1染色体编码
	 * @param r2Codes：r2染色体编码
	 * @return：变异后各可选构件选择方案的编码
	 */
	public StringBuffer mutCompSel1(float factor ,StringBuffer str1,StringBuffer str2,StringBuffer str3) {
		StringBuffer newCompSelCode = null;
			// 可选组件{CoreOnlineEngine，CoreGraphicEngine}
		// 可选组件{CoreOnlineEngine，CoreGraphicEngine}
					List<String> compNms = new ArrayList<String>();
//					compNms.add("S4");
//					compNms.add("S4-2");
//					compNms.add("BookingSystem");
//					compNms.add("QuickBooking");
					compNms.add("WebServer");
					compNms.add("WebServer2");
					compNms.add("WebServer3");
					String r1CmpNm = str1.toString().trim();
					String r2CmpNm = str2.toString().trim();
					String r3CmpNm = str3.toString().trim();
					String newCmpName = selComp1(factor, compNms, r1CmpNm, r2CmpNm, r3CmpNm);
					newCompSelCode=new StringBuffer(newCmpName);

//			// 可选组件{WebServer、WebServer2和WebServer3}
//			compNms.clear();
//			compNms.add("WebServer");
//			compNms.add("WebServer2");
//			compNms.add("WebServer3");
//
//			curCmpNm = srcCodes.get(19).toString().trim();
//			bestPCmpNm = bestPCodes.get(19).toString().trim();
//			r1CmpNm = r1Codes.get(19).toString().trim();
//			r2CmpNm = r2Codes.get(19).toString().trim();
//			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
//			newCompSelCodes.add(new StringBuffer(newCmpName));
//
//			// 可选组件{GraphicalReporting和GraphicalReporting2}
//			compNms.clear();
//			compNms.add("GraphicalReporting");
//			compNms.add("GraphicalReporting2");
//
//			curCmpNm = srcCodes.get(20).toString().trim();
//			bestPCmpNm = bestPCodes.get(20).toString().trim();
//			r1CmpNm = r1Codes.get(20).toString().trim();
//			r2CmpNm = r2Codes.get(20).toString().trim();
//			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
//			newCompSelCodes.add(new StringBuffer(newCmpName));
//
//			// 可选组件{UserManagement和UserManagement2}
//			compNms.clear();
//			compNms.add("UserManagement");
//			compNms.add("UserManagement2");
//
//			curCmpNm = srcCodes.get(21).toString().trim();
//			bestPCmpNm = bestPCodes.get(21).toString().trim();
//			r1CmpNm = r1Codes.get(21).toString().trim();
//			r2CmpNm = r2Codes.get(21).toString().trim();
//			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
//			newCompSelCodes.add(new StringBuffer(newCmpName));
		return newCompSelCode;
	}
//	public List<StringBuffer> mutCompSel(float factor, List<StringBuffer> srcCodes, List<StringBuffer> bestPCodes,
//			List<StringBuffer> r1Codes, List<StringBuffer> r2Codes) {
//		List<StringBuffer> newCompSelCodes = new ArrayList<StringBuffer>();
//		if (isEqualLen(srcCodes, bestPCodes, r1Codes, r2Codes)) {
//			// 可选组件{CoreOnlineEngine，CoreGraphicEngine}
//			List<String> compNms = new ArrayList<String>();
//			compNms.add("BookingSystem");
//			compNms.add("QuickBooking");
//			String curCmpNm = srcCodes.get(6).toString().trim();
//			String bestPCmpNm = bestPCodes.get(6).toString().trim();
//			String r1CmpNm = r1Codes.get(6).toString().trim();
//			String r2CmpNm = r2Codes.get(6).toString().trim();
//			String newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
//			newCompSelCodes.add(new StringBuffer(newCmpName));
//
////			// 可选组件{WebServer、WebServer2和WebServer3}
////			compNms.clear();
////			compNms.add("FileLoader");
////			compNms.add("FileLoaderPower");
////
////			curCmpNm = srcCodes.get(11).toString().trim();
////			bestPCmpNm = bestPCodes.get(11).toString().trim();
////			r1CmpNm = r1Codes.get(11).toString().trim();
////			r2CmpNm = r2Codes.get(11).toString().trim();
////			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
////			newCompSelCodes.add(new StringBuffer(newCmpName));
////
////			// 可选组件{GraphicalReporting和GraphicalReporting2}
////			compNms.clear();
////			compNms.add("Encoder");
////			compNms.add("EncoderPower");
////
////			curCmpNm = srcCodes.get(12).toString().trim();
////			bestPCmpNm = bestPCodes.get(12).toString().trim();
////			r1CmpNm = r1Codes.get(12).toString().trim();
////			r2CmpNm = r2Codes.get(12).toString().trim();
////			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
////			newCompSelCodes.add(new StringBuffer(newCmpName));
//////
//////			// 可选组件{UserManagement和UserManagement2}
//////			compNms.clear();
//////			compNms.add("UserManagement");
//////			compNms.add("UserManagement2");
//////
//////			curCmpNm = srcCodes.get(21).toString().trim();
//////			bestPCmpNm = bestPCodes.get(21).toString().trim();
//////			r1CmpNm = r1Codes.get(21).toString().trim();
//////			r2CmpNm = r2Codes.get(21).toString().trim();
//////			newCmpName = selComp(factor, compNms, curCmpNm, bestPCmpNm, r1CmpNm, r2CmpNm);
//////			newCompSelCodes.add(new StringBuffer(newCmpName));
//		}
//		return newCompSelCodes;
//	}

	/**
	 * 对某种组件有多个选择方案进行变异
	 * 
	 * @param factor:变异因子
	 * @param compNms:对于一种组件，其可供选择的组件名称列表
	 * @param curCmpNm：当前染色体中选择的组件名称
	 * @param bestPCmpNm：P最优染色中体选择的组件名称
	 * @param r1CmpNm：r1染色中选择的组件名称
	 * @param r2CmpNm:r2染色中选择的组件名称
	 * @return:变异后选择组件的名称
	 */
	public String selComp1(float factor, List<String> compNms, String r1CmpNm, String r2CmpNm, String r3CmpNm) {
		String newCmpName = null;
		int r1Val = getIdx(compNms, r1CmpNm);
		int r2Val = getIdx(compNms, r2CmpNm);
		int r3Val = getIdx(compNms, r3CmpNm);
		int size = compNms.size();
		if (r1Val >= 0 || r2Val >= 0 || r3Val >= 0 ) {
			int newVal = (int) Math.floor(r1Val+factor*(r2Val-r3Val));
			// 较最小值小
			if (newVal < 0) {
				newVal = r1Val / 2;
			}
			// 较最大值大
			if (newVal >= size) {
				newVal = (size + r1Val) / 2;
			}
			newCmpName = compNms.get(newVal);
		}
		return newCmpName;
	}

	/**
	 * 获取目标字符串在字符串数组中第一次出现的下标
	 * 
	 * @param elems:字符串数组
	 * @param tgtElem：目标字符串
	 * @return：目标字符串在字符串数组中第一次出现的下标
	 */
	public int getIdx(List<String> elems, String tgtElem) {
		String temp = null;
		int idx = -1;
		int size = elems.size();
		for (int i = 0; i < size; i++) {
			temp = elems.get(i);
			if (temp.equals(tgtElem)) {
				idx = i;
				break;
			}
		}
		return idx;
	}

	/**
	 * 对种群中的染色体按指定的目标进行从小到大的排序
	 * 
	 * @param which:第几个目标值
	 */
//	public void sortByObjVal(int which) {
//		int size = chroms.size();
//		for (int i = 0; i < size; i++) {
//			Chrom chromi = chroms.get(i);
//			float objVali = chromi.getObjVals().get(which);
//			for (int j = i + 1; j < size; j++) {
//				Chrom chromj = chroms.get(j);
//				float objValj = chroms.get(j).getObjVals().get(which);
//				if (Float.compare(objVali, objValj) > 0) {
//					Chrom tmpChrom = chromj;
//					chroms.set(j, chromi);
//					chroms.set(i, tmpChrom);
//					objVali = chroms.get(i).getObjVals().get(which);
//				}
//			}
//		}
//	}

	@Override
	public int[] mutingChoose(List<Chrom> chroms) {
		return null;
	}

	@Override
	public Population envSelect(Population tempPopu) {

		return null;
	}

	@Override
	public Population copy() {
		Population newPopu = new DFGAPopu();
		List<Chrom> newBestChroms = new ArrayList<Chrom>();
		for (Chrom bestChrom : bestChroms) {
			newBestChroms.add(bestChrom.copy());
		}
		newPopu.setBestChroms(newBestChroms);
		// 复制种群中的染色体
		for (int i = 0; i < chroms.size(); i++) {
			Chrom tmpChrom = chroms.get(i);
			newPopu.getChroms().add(tmpChrom.copy());
		}
		newPopu.setRandom(random);
		newPopu.setParameter(parameter);
		return newPopu;
	}

	public boolean isEqualLen(List<StringBuffer> srcCodes, List<StringBuffer> bestPCodes, List<StringBuffer> r1Codes,
			List<StringBuffer> r2Codes) {
		int srcCodeLen = srcCodes.size();
		int bestCodeLen = bestPCodes.size();
		int r1CodeLen = r1Codes.size();
		int r2CodeLen = r2Codes.size();
		return srcCodeLen == bestCodeLen && srcCodeLen == r1CodeLen && srcCodeLen == r2CodeLen;
	}

	public static ArrayList<Float> getMutFactors() {
		return mutFactors;
	}

	public static void setMutFactors(ArrayList<Float> mutFactors) {
		DFGAPopu.mutFactors = mutFactors;
	}

	public static ArrayList<Float> getCrobs() {
		return crobs;
	}

	public static void setCrobs(ArrayList<Float> crobs) {
		DFGAPopu.crobs = crobs;
	}

	public static List<Chrom> getArchieves() {
		return archieves;
	}

	public static void setArchieves(List<Chrom> archieves) {
		DFGAPopu.archieves = archieves;
	}

	public static void main(String[] args) {
		System.out.println(Math.tan(0.5f - 0.5f) * Math.PI);
		// System.out.println(0.04+0.3152107443794341);
	}
}
